package de.chessgame.client.renderer.tileentity;

import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

import java.util.Calendar;

import net.minecraft.block.Block;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;

import de.chessgame.ChessGameMod;
import de.chessgame.block.BlockChessBoard;
import de.chessgame.gamelogic.piece.Fraction;
import de.chessgame.gamelogic.piece.Piece;
import de.chessgame.gamelogic.piece.Type;
import de.chessgame.src.*;
import de.chessgame.tileentity.TileEntityChessBoard;

@SideOnly(Side.CLIENT)
public class TileEntityChessBoardRenderer extends TileEntitySpecialRenderer {

	// textures:
	private static final ResourceLocation textureBlockChessTable = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/blockchessboard.png");

	// pieces
	private static final ResourceLocation textureKingWhite = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/kingwhitetexture.png");
	private static final ResourceLocation textureQueenWhite = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/queenwhitetexture.png");
	private static final ResourceLocation textureRookWhite = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/rookwhitetexture.png");
	private static final ResourceLocation textureKnightWhite = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/knightwhitetexture.png");
	private static final ResourceLocation textureBishopWhite = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/bishopwhitetexture.png");
	private static final ResourceLocation texturePawnWhite = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/pawnwhitetexture.png");

	private static final ResourceLocation textureKingBlack = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/kingblacktexture.png");
	private static final ResourceLocation textureQueenBlack = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/queenblacktexture.png");
	private static final ResourceLocation textureRookBlack = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/rookblacktexture.png");
	private static final ResourceLocation textureKnightBlack = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/knightblacktexture.png");
	private static final ResourceLocation textureBishopBlack = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/bishopblacktexture.png");
	private static final ResourceLocation texturePawnBlack = new ResourceLocation(
			ChessGameMod.MODID + ":" + "textures/model/pawnblacktexture.png");

	// models:
	private ModelChessBoard modelChessTable = new ModelChessBoard();

	// pieces
	private ModelKing modelKing = new ModelKing();
	private ModelQueen modelQueen = new ModelQueen();
	private ModelRook modelRook = new ModelRook();
	private ModelKnight modelKnight = new ModelKnight();
	private ModelBishop modelBishop = new ModelBishop();
	private ModelPawn modelPawn = new ModelPawn();

	public void renderTileEntityAt(TileEntityChessBoard entity, double x,
			double y, double z, float time) {

		float direction = entity.blockMetadata;
		float rotZ = 0.0F;

		if (direction == 2) {
			rotZ = 180.0F;
		}

		if (direction == 4) {
			rotZ = 90.0F;
		}

		if (direction == 5) {
			rotZ = 270.0F;
		}
		GL11.glPushMatrix();
		GL11.glTranslated(x + 0.5, y + 0.75, z + 0.5);
		GL11.glRotatef(180.0f, 180.0f, 0.0f, 0.0f);
		GL11.glRotatef(rotZ, 0.0f, rotZ, 0.0f);
		GL11.glScalef(0.5f, 0.5f, 0.5f);
		this.bindTexture(textureBlockChessTable);
		GL11.glPushMatrix();
		// board:
		this.modelChessTable.render(0.0625f);
		renderPieces(entity);
		GL11.glPopMatrix();
		GL11.glPopMatrix();

	}

	public void renderTileEntityAt(TileEntity p_147500_1_, double p_147500_2_,
			double p_147500_4_, double p_147500_6_, float p_147500_8_) {
		this.renderTileEntityAt((TileEntityChessBoard) p_147500_1_,
				p_147500_2_, p_147500_4_, p_147500_6_, p_147500_8_);
	}

	private void renderPieces(TileEntityChessBoard entity) {
		for (int y = 0; y < 8; y++) {
			for (int x = 0; x < 8; x++) {
				Piece piece = entity.getPieceOnCoordinate(x, y);
				renderPieceAtPosition(piece, x, y);
			}
		}
	}

	private void renderPieceAtPosition(Piece piece, int x, int y) {
		if (piece != null && piece.getType() != null) {
			GL11.glPushMatrix();
			Fraction fraction = piece.getFraction();
			Type type = piece.getType();
			GL11.glScalef(0.5f, 0.5f, 0.5f);
			GL11.glTranslated(-1.75, 1.375, -2.25);
			GL11.glTranslated(x * 0.5, 0, (8 - y) * 0.5);
			if (fraction == Fraction.WHITE) {
				GL11.glRotatef(90f, 0, 90f, 0);
			} else {
				GL11.glRotatef(90, 0, -90f, 0);
			}
			this.bindTexture(getRessourceLocationFromTypeAndFraction(fraction,
					type));
			GL11.glPushMatrix();
			renderPiece(type, 0.0625f);
			GL11.glPopMatrix();
			GL11.glPopMatrix();
		}
	}

	private ResourceLocation getRessourceLocationFromTypeAndFraction(
			Fraction fraction, Type type) {
		if (fraction == Fraction.WHITE) {
			switch (type) {
			case KING:
				return textureKingWhite;

			case QUEEN:

				return textureQueenWhite;

			case ROOK:
				return textureRookWhite;

			case KNIGHT:
				return textureKnightWhite;

			case BISHOP:
				return textureBishopWhite;

			case PAWN:
				return texturePawnWhite;

			default:
				return null;
			}
		} else {
			switch (type) {
			case KING:
				return textureKingBlack;

			case QUEEN:

				return textureQueenBlack;

			case ROOK:
				return textureRookBlack;

			case KNIGHT:
				return textureKnightBlack;

			case BISHOP:
				return textureBishopBlack;

			case PAWN:
				return texturePawnBlack;

			default:
				return null;
			}
		}
	}

	private void renderPiece(Type type, float f5) {
		switch (type) {
		case KING:
			GL11.glRotatef(90, 0, 90f, 0);
			modelKing.render(f5);
			return;

		case QUEEN:

			modelQueen.render(f5);
			return;

		case ROOK:
			modelRook.render(f5);
			return;

		case KNIGHT:
			modelKnight.render(f5);
			return;

		case BISHOP:
			modelBishop.render(f5);
			return;

		case PAWN:
			modelPawn.render(f5);
			return;

		default:
			return;
		}
	}
}